<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
</head>

<body>
  <h3> Local Video </h3>
  <video id="localVideo" width="160" height="120" autoplay muted></video> <br />

  <h3> Remote Video </h3>
  <div id="remoteVideos"></div> <br />

  <h3> Logs </h3>
  <div id="logs"></div>


</body>

<script>
  navigator.mediaDevices.getUserMedia({ video: true, audio: true })
    .then(stream => {
      let pc = new RTCPeerConnection({
        iceServers: [{
          urls: 'stun:stun.l.google.com:19302'
        }]
      })
      pc.ontrack = function (event) {
        if (event.track.kind === 'audio') {
          return
        }

        let el = document.createElement(event.track.kind)
        el.srcObject = event.streams[0]
        el.autoplay = true
        el.controls = true
        document.getElementById('remoteVideos').appendChild(el)

        event.track.onmute = function (event) {
          el.play()
        }

        event.streams[0].onremovetrack = ({ track }) => {
          if (el.parentNode) {
            el.parentNode.removeChild(el)
          }
        }
      }

      document.getElementById('localVideo').srcObject = stream
      stream.getTracks().forEach(track => pc.addTrack(track, stream))

      // pc.createOffer().then(offer => {
      //         pc.setLocalDescription(offer)
      //         console.log("offer:\r\n")
      //         console.log(offer)
      //         //ws.send(JSON.stringify({ event: 'offer', data: JSON.stringify(offer) }))
      //       })
      let ws = new WebSocket("{{.}}")
      let i=0
      pc.onicecandidate = e => {
        if (!e.candidate) {
          return
        }
        i++
        document.getElementById('logs').innerHTML +=i.toString() +"."+pc.iceGatheringState.toString()+" "+ JSON.stringify(e.candidate) + '<br>'
        ws.send(JSON.stringify({event: 'candidate', data: JSON.stringify(e.candidate)}))
        
        //this.wsSend(JSON.stringify({ event: 'candidate', data: JSON.stringify(e.candidate) }))
      }

      ws.onclose = function (evt) {
        window.alert("Websocket has closed")
      }

      ws.onmessage = function (evt) {
        let msg = JSON.parse(evt.data)
        if (!msg) {
          return console.log('failed to parse msg')
        }

        switch (msg.event) {
          case 'offer':
            let offer = JSON.parse(msg.data)
            console.log("offer:" + msg.data)
            if (!offer) {
              return console.log('failed to parse answer')
            }
            pc.setRemoteDescription(offer)
            pc.createAnswer().then(answer => {
              pc.setLocalDescription(answer)
              ws.send(JSON.stringify({ event: 'answer', data: JSON.stringify(answer) }))
            })
            return

          case 'answer':
            let answer = JSON.parse(msg.data)
            console.log("answer:" + answer)
            if (!answer) {
              return console.log('failed to parse answer')
            }
            pc.setRemoteDescription(answer)
            // pc.createAnswer().then(answer => {
            //   pc.setLocalDescription(answer)
            //   ws.send(JSON.stringify({event: 'answer', data: JSON.stringify(answer)}))
            // })
            return

          case 'anotherClientJoin':
            // let anotherClientJoinMsg = JSON.parse(msg.data)
            console.log("anotherClientJoin")
            console.log(msg.data)
            pc.createOffer().then(offer => {
              pc.setLocalDescription(offer)
              console.log("offer:\r\n")
              console.log(offer)
              ws.send(JSON.stringify({ event: 'offer', data: JSON.stringify(offer) }))
            })
            return

          case 'candidate':
            let candidate = JSON.parse(msg.data)
            console.log(msg.data)
            if (!candidate) {
              return console.log('failed to parse candidate')
            }
            console.log(candidate)
            pc.addIceCandidate(candidate)
        }
      }

      ws.onerror = function (evt) {
        console.log("ERROR: " + evt.data)
      }

      this.wsSend = function (message, callback) {
        waitForConnection(function () {
          console.log("1")
          ws.send(message);
          if (typeof callback !== 'undefined') {
            callback();
          }
        }, 1000);
      };

      this.waitForConnection = function (callback, interval) {
        if (ws.readyState === 1) {
          callback();
        } else {
          var that = this;
          // optional: implement backoff for interval here
          console.log("2")
          setTimeout(function () {
            console.log("3")
            that.waitForConnection(callback, interval);
          }, interval);
        }
      };
      let hasAnotherClient = false;
      if (hasAnotherClient) {
        pc.createOffer().then(offer => {
          pc.setLocalDescription(offer)
          console.log("offer:\r\n")
          console.log(offer)
          this.wsSend(JSON.stringify({ event: 'offer', data: JSON.stringify(offer) }))
          //  let sendFinish=false;             
          // while(!sendFinish){
          //    sleep(200).then(function(){
          //    if(ws.readyState === 1){
          //     sendFinish = true;
          //    ws.send(JSON.stringify({event: 'offer', data: JSON.stringify(offer)}))
          //  }
          // })                
          // }
        })
      }

    }).catch(window.alert)
</script>

</html>